package com.tim.socket;

import java.net.*;
import java.io.*;
import java.util.*;

public class ChartServer4 {

	private ServerSocket server;
	// 消息广播者
	private BManager bMan = new BManager();

	// 构造函数
	public ChartServer4() {
	}

	// 启动服务器
	void startServer() {
		try {
			// 创建服务器套接字
			server = new ServerSocket(8888);
			System.out.println("服务器套接字建立完毕");
			while (true) {
				// 若客户机提请求，socket连接
				Socket socket = server.accept();
				// 启动线程
				new Chat_Thread(socket);
				// 添加套接字
				bMan.add(socket);
				// 使用套接字输出当前聊天人数
				bMan.sendClientInfo();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		ChartServer4 server = new ChartServer4();
		server.startServer();
	}

	// 与客户机进行通信的线程累
	class Chat_Thread extends Thread {
		// 套接字引用变量
		Socket socket;
		// 引用套接字输入流；
		private BufferedReader reader;
		// 引用套接字输出流；
		private PrintWriter writer;

		// 构造函数
		Chat_Thread(Socket socket) throws IOException {
			this.socket = socket;
			reader = new BufferedReader(new InputStreamReader(socket
					.getInputStream(), "UTF-8"));
			writer = new PrintWriter(socket.getOutputStream(), true);
			start();
		}

		public void run() {
			try {
				String msg = reader.readLine();
				while(!"bye".equalsIgnoreCase(msg)) {
					// 从输出流获取信息
					System.out.println("客户端信息： " + msg);
					// 向所有客户机传送信息
					bMan.sendToAll(msg);
					msg = reader.readLine();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				// 从消息广播者立标中删除socket
				try {
					bMan.remove(socket);
					if (reader != null)
						reader.close();
					if (writer != null)
						writer.close();
					if (socket != null)
						socket.close();
					reader = null;
					writer = null;
					socket = null;
					System.out.println("客户机离开");
					// 向所有客户机传送当前连接数
					bMan.sendClientInfo();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

// 消息广播者类，继承Vector类
@SuppressWarnings({ "unchecked", "serial" })
class BManager extends Vector {
	// 构造函数
	BManager() {
	}

	void add(Socket sock) {
		// 添加套接字
		super.add(sock);
	}

	void remove(Socket sock) {
		// 删除套接字
		super.remove(sock);
	}

	// 向所有客户机传送消息，同步化方法。
	synchronized void sendToAll(String msg) {
		// 输出流
		PrintWriter writer = null;
		// 套接字
		Socket sock;
		// 执行循环
		for (int i = 0; i < size(); i++) {
			// 获取第i个套接字
			sock = (Socket) elementAt(i);
			try {
				// 获取第i个套接字输出流
				writer = new PrintWriter(sock.getOutputStream(), true);
			} catch (Exception ie) {
				ie.printStackTrace();
			}
			// 使用第i各套接字输出流，输出消息
			if (writer != null)
				writer.println(msg);
		}
	}

	// 向所有客户机发送当前聊天人数
	synchronized void sendClientInfo() {
		String info = "当前聊天人数：" + size();
		System.out.println(info);
		sendToAll(info);
	}
}